import { createApp, h, getCurrentInstance } from 'vue';
import Modal from './modal.vue';
import Button from '../button/button.vue';
import Locale from '../../mixins/locale';
import { isClient } from '../../utils/index';

const prefixCls = 'ivu-modal-confirm';

Modal.newInstance = properties => {
  if (!isClient) return;
  const _props = properties || {};

  const container = document.createElement('div');
  document.body.appendChild(container);

  let _instance = null;

  const Instance = createApp({
    mixins: [Locale],
    data() {
      return Object.assign({}, _props, {
        visible: false,
        width: 375,
        title: '',
        body: '',
        iconType: '',
        iconName: '',
        okText: undefined,
        cancelText: undefined,
        showCancel: false,
        loading: false,
        buttonLoading: false,
        scrollable: false,
        closable: true,
        closing: false, // 关闭有动画，期间使用此属性避免重复点击
      });
    },
    render() {
      let footerVNodes = [];
      if (this.showCancel) {
        footerVNodes.push(
          h(
            Button,
            {
              type: 'default',
              onClick: this.cancel,
            },
            () => this.localeCancelText
          )
        );
      }
      footerVNodes.push(
        h(
          Button,
          {
            type: 'primary',
            loading: this.buttonLoading,
            onClick: this.ok,
          },
          () => this.localeOkText
        )
      );

      // render content
      let body_render;
      if (this.render) {
        body_render = h(
          'div',
          {
            class: `${prefixCls}-body ${prefixCls}-body-render`,
          },
          [this.render(h)]
        );
      } else {
        body_render = h(
          'div',
          {
            class: `${prefixCls}-body`,
            style: { textAlign: 'center' },
          },
          [
            h(
              'span',
              {
                class: this.iconTypeCls,
              },
              [
                h('i', {
                  class: this.iconNameCls,
                }),
              ]
            ),
            h('span', {
              innerHTML: this.body,
            }),
          ]
        );
      }

      // when render with no title, hide head
      let head_render;
      if (this.title) {
        head_render = h(
          'div',
          {
            class: `${prefixCls}-head`,
            style: {
              borderBottom: '1px solid #e8eaec',
              width: 'calc(100% + 32px)',
              position: 'relative',
              left: '-16px',
              padding: '0 16px 16px 16px',
            },
          },
          [
            h('div', {
              class: `${prefixCls}-head-title`,
              innerHTML: this.title,
            }),
          ]
        );
      }

      return h(
        Modal,
        Object.assign(
          {},
          _props,
          {
            width: this.width,
            scrollable: this.scrollable,
            closable: this.closable,
            ref: 'modal',
          },
          {
            modelValue: this.visible,
            'onUpdate:modelValue': status => (this.visible = status),
            'onOn-cancel': this.cancel,
          }
        ),
        () =>
          h(
            'div',
            {
              class: prefixCls,
            },
            [
              head_render,
              body_render,
              h(
                'div',
                {
                  class: `${prefixCls}-footer`,
                },
                footerVNodes
              ),
            ]
          )
      );
    },
    computed: {
      iconTypeCls() {
        return [`${prefixCls}-head-icon`, `${prefixCls}-head-icon-${this.iconType}`];
      },
      iconNameCls() {
        return ['ivu-icon', `ivu-icon-${this.iconName}`];
      },
      localeOkText() {
        if (this.okText) {
          return this.okText;
        } else {
          return this.t('i.modal.okText');
        }
      },
      localeCancelText() {
        if (this.cancelText) {
          return this.cancelText;
        } else {
          return this.t('i.modal.cancelText');
        }
      },
    },
    methods: {
      cancel() {
        if (this.closing) return;
        this.$refs.modal.visible = false;
        this.buttonLoading = false;
        this.onCancel();
        this.remove();
      },
      ok() {
        if (this.closing) return;
        if (this.loading) {
          this.buttonLoading = true;
        } else {
          this.$refs.modal.visible = false;
          this.remove();
        }
        this.onOk();
      },
      remove() {
        this.closing = true;
        setTimeout(() => {
          this.closing = false;
          this.destroy();
        }, 300);
      },
      destroy() {
        Instance.unmount();
        document.body.removeChild(container);
        this.onRemove();
      },
      onOk() {},
      onCancel() {},
      onRemove() {},
    },
    created() {
      _instance = getCurrentInstance();
    },
  });

  Instance.mount(container);
  const modal = _instance.refs.modal;

  return {
    show(props) {
      modal.$parent.showCancel = props.showCancel;
      modal.$parent.iconType = props.icon;

      switch (props.icon) {
        case 'info':
          modal.$parent.iconName = 'ios-information-circle-outline';
          break;
        case 'success':
          modal.$parent.iconName = 'ios-checkmark-circle-outline';
          break;
        case 'warning':
          modal.$parent.iconName = 'ios-alert-outline';
          break;
        case 'error':
          modal.$parent.iconName = 'ios-close-circle-outline';
          break;
        case 'confirm':
          modal.$parent.iconName = 'ios-help-circle-outline';
          break;
      }

      if ('width' in props) {
        modal.$parent.width = props.width;
      }

      if ('closable' in props) {
        modal.$parent.closable = props.closable;
      }

      if ('title' in props) {
        modal.$parent.title = props.title;
      }

      if ('content' in props) {
        modal.$parent.body = props.content;
      }

      if ('okText' in props) {
        modal.$parent.okText = props.okText;
      }

      if ('cancelText' in props) {
        modal.$parent.cancelText = props.cancelText;
      }

      if ('onCancel' in props) {
        modal.$parent.onCancel = props.onCancel;
      }

      if ('onOk' in props) {
        modal.$parent.onOk = props.onOk;
      }

      // async for ok
      if ('loading' in props) {
        modal.$parent.loading = props.loading;
      }

      if ('scrollable' in props) {
        modal.$parent.scrollable = props.scrollable;
      }

      // notice when component destroy
      modal.$parent.onRemove = props.onRemove;

      modal.visible = true;
    },
    remove() {
      modal.visible = false;
      modal.$parent.buttonLoading = false;
      modal.$parent.remove();
    },
    component: modal,
  };
};

export default Modal;
